/* ChatActivity.java
 *
 * Copyright 2011-2012 Aleksey Konovalov, r.u.s.h.a.n.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 * 
 */

package org.jimm.app;

import org.jimm.comm.Util;
import org.jimm.db.JimmDatabase.History;
import org.jimm.message.Message;
import org.jimm.message.PlainMessage;
import org.jimm.protocol.Contact;
import org.jimm.protocol.Protocol;
import org.jimm.protocol.XStatusInfo;
import org.jimm.service.JimmService;
import org.jimm.service.Preferences;

import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.text.format.Time;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

/**
 * @author Aleksey Konovalov, r.u.s.h.a.n.
 */
public class ChatActivity extends JimmActivity {

    private static final String LOG_TAG = "Jimm:ChatActivity";
    public static final String CONTACT_ID_EXTRA = "ContactID"; // UIN or JID
    public static final String ACCOUNT_ID_EXTRA = "AccountID";
    public static final String MSG_TEXT_EXTRA = "messageText";

    private EditText editMessage;
    private String accountId;
    private String contactId;
    private Protocol protocol;
    private Contact contact;
    private LayoutInflater inflater;
    private BaseAdapter chatMessageAdapter;
    private BaseAdapter chatTabAdapter;


    private final JimmApplication app = JimmApplication.getInstance();
    private JimmService service = app.getService();
    private Preferences p = JimmApplication.getInstance().getPreferences();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate_(savedInstanceState);

        setContentView(R.layout.chat);

        Intent intent = getIntent();
        inflater = LayoutInflater.from(this);
        contactId = intent.getStringExtra(CONTACT_ID_EXTRA);
        accountId = intent.getStringExtra(ACCOUNT_ID_EXTRA);
        String messageText = intent.getStringExtra(MSG_TEXT_EXTRA);

        protocol = JimmApplication.getInstance().getAccountsManager().getProtocol(accountId);
        service.chatActivity = this;
        if (protocol == null) {
            Log.e(LOG_TAG, "Can't find account");
            finish();
            return;
        }

        contact = protocol.getItemByUIN(contactId);
        if (contact == null) {
            Log.e(LOG_TAG, "contact not found");
            finish();
            return;
        }

        contact.updateChatState(true);

        removeReadMessages();

        String[] d = new String[]{
                History.ACCOUNT,
                History.CONTACT,
                History.DATE,
                History.FLAGS,
                History.MESSAGE
        };

        Cursor c = managedQuery(History.CONTENT_URI, d, History.ACCOUNT + " = " + accountId + " AND " + History.CONTACT + " = " + contactId, null, History.DATE + " DESC");

        if (c.moveToLast()) {
            do {
                String accountUid = c.getString(c.getColumnIndex(History.ACCOUNT));
                String contactUid = c.getString(c.getColumnIndex(History.CONTACT));
                long date = c.getLong(c.getColumnIndex(History.DATE));
                short flags = c.getShort(c.getColumnIndex(History.FLAGS));
                String text = c.getString(c.getColumnIndex(History.MESSAGE));

                PlainMessage msg = new PlainMessage(accountUid, contactUid, date, text, (flags & History.FLAG_RECEIVED_MESSAGE) != 0);
                msg.isReaded = true;
                contact.messages.add(msg);

            } while (c.moveToPrevious());
        } else {
            Log.e(LOG_TAG, "History not found in DB [contactId = " + contactId + "]");
        }
 
        //contact.setMessagesIsReaded();

        editMessage = (EditText) findViewById(R.id.chat_message_edit);

        editMessage.setText(messageText);

        ImageButton buttonSend = (ImageButton) findViewById(R.id.chat_send_button);
        ImageButton buttonSmile = (ImageButton) findViewById(R.id.chat_smile_button);

        buttonSmile.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivityForResult(new Intent(ChatActivity.this, SmileActivity.class), 1);
            }
        });

        buttonSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //if (protocol.isConnected()) {
                String msg = editMessage.getText().toString().trim();
                if (msg.length() > 0) {
                    sendMessage(msg);
                    editMessage.setText("");
                }
                //}
            }
        });

        if (p.sendByEnter) {
            editMessage.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if (event.getAction() == KeyEvent.ACTION_DOWN) {
                        if (keyCode == KeyEvent.KEYCODE_ENTER) {
                            String msg = editMessage.getText().toString().trim();
                            if (msg.length() > 0) {
                                sendMessage(msg);
                                editMessage.setText("");
                            }
                            return true;
                        }
                    }
                    return false;
                }
            });

            invalidate();
        }

        chatMessageAdapter = new BaseAdapter() {
            @Override
            public int getCount() {
                return contact.messages.size();
            }

            @Override
            public PlainMessage getItem(int position) {
                return contact.messages.get(position);
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {

                if (convertView == null)
                    convertView = inflater.inflate(R.layout.chat_item, null);

                PlainMessage msg = getItem(position);

                msg.isReaded = true;

                Time time = new Time();
                time.set(msg.getNewDate());

                if (msg.isIncoming())
                    convertView.setBackgroundColor(getResources().getColor(R.color.chat_message_background_a));
                else
                    convertView.setBackgroundColor(getResources().getColor(R.color.chat_message_background_b));

                ImageView msgImage = (ImageView) convertView.findViewById(R.id.msg_icon);
                msgImage.setImageResource(msg.getIcon());

                TextView msgNick = (TextView) convertView.findViewById(R.id.msg_nick);
                msgNick.setText(msg.getName());
                //msgNick.setTextColor(getResources().getColor(msg.getTextColor()));

                TextView msgTime = (TextView) convertView.findViewById(R.id.msg_time);
                msgTime.setText(time.format(" (%H:%M:%S %d/%m/%Y)"));
                //msgTime.setTextColor(getResources().getColor(msg.getTextColor()));

                TextView msgText = (TextView) convertView.findViewById(R.id.msg_text);
                msgText.setText(ChatMessageFormatter.getFormattedText(ChatActivity.this, msg));

                return convertView;
            }
        };
        ListView chatListView = (ListView) findViewById(R.id.chat_history_list);
        chatListView.setAdapter(chatMessageAdapter);
        chatListView.setOnCreateContextMenuListener(this);

        if (app.chatPages.indexOf(contact) < 0) {
        	app.chatPages.add(contact);
        }

        chatTabAdapter = new BaseAdapter() {  
        	  
            @Override  
            public int getCount() {  
                return app.chatPages.size();  
            }  
      
            @Override  
            public Contact getItem(int position) {  
                return app.chatPages.get(position);  
            }  
      
            @Override  
            public long getItemId(int position) {  
                return position;  
            }  
      
            @Override  
            public View getView(int position, View convertView, ViewGroup parent) {  
                if (convertView == null)
                    convertView = inflater.inflate(R.layout.chat_tabs, null);
                
                Contact c = getItem(position);

                TextView textName = (TextView) convertView.findViewById(R.id.chat_tab_nick_text);
                ImageView imageStatus = (ImageView) convertView.findViewById(R.id.chat_tab_status_image);
                ImageView imageXStatus = (ImageView) convertView.findViewById(R.id.chat_tab_xstatus_image);
                
	            if (c.getUnreadMessageCount() > 0) {
	            	imageStatus.setImageResource(R.drawable.ic_message);
	            } else if (c.isTyping()) {
	            	imageStatus.setImageResource(R.drawable.ic_contact_typing);
	            } else {
	            	imageStatus.setImageResource(c.getStatusIcon());
	            }
	
	            if (c.getXStatusIndex() == 0 || c.getXStatusIndex() == XStatusInfo.XSTATUS_NONE) {
	            	imageXStatus.setVisibility(ImageView.GONE);
	            } else {
	            	imageXStatus.setVisibility(ImageView.VISIBLE);
	            	imageXStatus.setImageResource(c.getXStatusIcon());
	            }
	            
	            if (c.equals(contact)) {
	            	convertView.setBackgroundColor(getResources().getColor(R.color.chat_tab_selected));
	            } else {
	            	convertView.setBackgroundColor(getResources().getColor(R.color.chat_tab_normal));
	            }
	            	
	            
	            textName.setText(c.getName());
	            
                return convertView;
            }  
      
        };
        ListView chatTabView = (ListView) findViewById(R.id.chat_tabs_list);
        chatTabView.setAdapter(chatTabAdapter);
        chatTabView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View v, int arg2, long arg3) {

            	contact = (Contact) chatTabAdapter.getItem(arg2);
            	protocol = contact.getProtocol();

            	chatTabAdapter.notifyDataSetChanged();
				chatMessageAdapter.notifyDataSetChanged();
            }
        });
        // remove chat on long click
        chatTabView.setOnItemLongClickListener(new OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
				for (int i = 0; i < app.chatPages.size(); i++) {
                    if (app.chatPages.get(i).equals(contact)) {
                        app.chatPages.remove(i);
                        contact.updateChatState(false);
                        finish();
                    }
                }
				return false;
			}
        });
        
        
        invalidate();

        //NotificationMan.updateNewMsgNotification();
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK && requestCode == 1) {

            String smile = data.getStringExtra("smile");
            editMessage = (EditText) findViewById(R.id.chat_message_edit);

            int start = editMessage.getSelectionStart();
            int end = editMessage.getSelectionEnd();
            editMessage.getText().replace(Math.min(start, end), Math.max(start, end), smile, 0, smile.length());
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    public static final int MENU_REMOVE_CHAT = 100;
    public static final int MENU_COPY_TEXT = 200;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        menu.add(Menu.FIRST, MENU_REMOVE_CHAT, 0, R.string.chat_remove).setIcon(android.R.drawable.ic_menu_close_clear_cancel);
        menu.add(Menu.FIRST, Contact.USER_MENU_USER_INFO, 0, R.string.user_info);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {


        switch (item.getItemId()) {
            case MENU_REMOVE_CHAT:
                for (int i = 0; i < app.chatPages.size(); i++) {
                    if (app.chatPages.get(i).equals(contact)) {
                        app.chatPages.remove(i);
                        contact.updateChatState(false);
                        finish();
                    }
                }
                break;

            case Contact.USER_MENU_USER_INFO:
                protocol.showUserInfo(contact, this);
                break;
        }
        return false;
    }


    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        //ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);

        menu.add(Menu.FIRST, MENU_COPY_TEXT, 0, android.R.string.copy);

        if (!JimmApplication.isClipBoardEmpty()) {
            menu.add(Menu.FIRST, Contact.USER_MENU_PASTE, 0, android.R.string.paste);
            menu.add(Menu.FIRST, Contact.USER_MENU_QUOTE, 0, R.string.quote);
        }
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {

        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

        switch (item.getItemId()) {

            case MENU_COPY_TEXT:
                Message m = contact.messages.get(info.position);
                if (null == m) {
                    return true;
                }
                long yesterday = Util.createCurrentDate(false) - 23 * 60 * 60;
                String msg = m.getText();
                if (!m.isIncoming()) {
                    msg = "*" + m.getName() + " " + msg;
                }
                String time = Util.getDateString(m.getNewDate(), yesterday < m.getNewDate());
                JimmApplication.setClipBoardText(m.isIncoming(), time, m.getName(), msg);
                break;

            case Contact.USER_MENU_PASTE:
            case Contact.USER_MENU_QUOTE:
                editMessage = (EditText) findViewById(R.id.chat_message_edit);
                editMessage.setText(editMessage.getText() + JimmApplication.getClipBoardText(Contact.USER_MENU_QUOTE == item.getItemId()));
                break;

            default:
                //new ContactMenu(protocol, contact).doAction(item.getItemId());

        }

        return true;
    }

    @Override
    public final void invalidate() {

        runOnUiThread(new Runnable() {

            public void run() {
                chatMessageAdapter.notifyDataSetChanged();
                chatTabAdapter.notifyDataSetChanged();
            }
        });
    }


    public Protocol getProtocol() {
        return protocol;
    }

    public Contact getContact() {
        return contact;
    }

    void sendMessage(String message) {
        ContentValues values = new ContentValues();

        String accountUid = protocol.getUserId();
        String contactUid = contact.getUserId();
        long date = System.currentTimeMillis();

        values.put(History.ACCOUNT, accountUid);
        values.put(History.CONTACT, contactUid);
        values.put(History.DATE, date);
        values.put(History.FLAGS, 0);
        values.put(History.MESSAGE, message);

        getContentResolver().insert(History.CONTENT_URI, values);

        // �������� ���������
        protocol.sendMessage(contact, message, true);
        contact.messages.add(new PlainMessage(accountUid, protocol.getNick(), date, message, false));

        chatMessageAdapter.notifyDataSetChanged();
    }

    public void removeReadMessages() {
        getContact().messages.clear();
    }
}
